package com.dongdong.filter;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.dongdong.em.Result;
import com.dongdong.em.ResultEnum;
import com.dongdong.util.JWTUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.annotation.Order;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.Set;

@Order(-1)
@Component
public class LoginFilter implements GlobalFilter {

    @Autowired
    private JWTUtil jwtUtil;

    @Value("#{'${gateway.exclusion.url}'.empty ? null : '${gateway.exclusion.url}'.split(',')}")     //多个参数用#    单个参数用$
    private Set<String> url;//有序集合
    //路径匹配API
    private AntPathMatcher antPathMatcher = new AntPathMatcher();

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //1.获取请求头信息
        ServerHttpRequest request = exchange.getRequest();
        //1.路径匹配 - 获取请求路径
        String path = request.getURI().getPath();//返回String类型
        //2.遍历从配置文件中获取到的多个路径

        //如果只需要拦截购物车   就定义一个变量  直接反向逻辑 就可以了    但是如果是多个就不要加了
//        boolean flage = false;
        for (String urls : url) {
            if (antPathMatcher.match(urls, path)) {//API  boolean类型
                //3.匹配就放行
//                flage = true;
//                break;
                return chain.filter(exchange);
            }
        }

//        if (flage){//为true的情况下去解析token
        HttpHeaders headers = request.getHeaders();
        String token = headers.getFirst("Autherizetion");//获取第一个参数
        //2.判断token是否存在
        if (token == null || "".equals(token)) {
            return getVoidMono(exchange);
        }
        try {
            //如果存在token进行解析
            jwtUtil.parseJwt(token);
        } catch (Exception e) {
            //为空  与上面一样  快捷键 Ctrl+shift+M  封装
            return getVoidMono(exchange);
        }
//        }
        /*一路绿灯  放过*/
        return chain.filter(exchange);
    }

    //返回错误信息状态码
    private Mono<Void> getVoidMono(ServerWebExchange exchange) {
        //返回响应的东西
        ServerHttpResponse response = exchange.getResponse();
        response.setStatusCode(HttpStatus.OK);//401   OK:说明请求和响应是完整的   可以直接将下边的东西返回给你
        //设置响应头  避免中文乱码
        response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
        //设置响应内容   枚举类拿过来用
        Result result = Result.ZHRESPONSE(ResultEnum.TOKEN_LOSE_EFFICACY);//token失效
        //不输出为null的字段     想办法将result响应信息放到response中   并且不为空    策略：使用这个策略不会有null值
        DataBuffer wrap = response.bufferFactory().wrap(JSONObject.toJSONBytes(result, SerializerFeature.WriteMapNullValue));
        return response.writeWith(Mono.just(wrap));//默认just  可以放任何类型
    }

//    @Override
//    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
//        //获取请求头信息
//        ServerHttpRequest request = exchange.getRequest();
//        HttpHeaders headers = request.getHeaders();
//        String token = headers.getFirst("Autherizetion");
//        //判断是有存在token
//        if (token == null || "".equals(token)) {
//            return getVoidMono(exchange);
//        }
//        //如果存在token进行解析
//        try {
//            jwtUtil.parseJwt(token);
//        } catch (Exception e) {
//            return getVoidMono(exchange);
//        }
//        return chain.filter(exchange);
//    }
//    //返回错误状态码
//    private Mono<Void> getVoidMono(ServerWebExchange exchange) {
//        ServerHttpResponse response = exchange.getResponse();
//        //设置响应码
//        response.setStatusCode(HttpStatus.UNAUTHORIZED);
//        //设置响应头编码
//        response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
//        //设置响应内容
//        Result result = Result.ZHRESPONSE(ResultEnum.TOKEN_LOSE_EFFICACY);//token失效
//        //不输出为null的字段
//        byte[] bytes = JSONObject.toJSONBytes(result, SerializerFeature.WriteMapNullValue);
//        DataBuffer wrap = response.bufferFactory().wrap(bytes);
//        return response.writeWith(Mono.just(wrap));
//    }
}
